package com.watson.juc;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author watson
 * @date 2021/8/2 13:53
 * @Description: TODO
 **/
public class CASDemo {
    //比较并交换
    public static void main(String[] args) {
        // 设置初始值
        AtomicInteger atomicInteger = new AtomicInteger(2020);

        //如果期望值达到了，那么就修改更新，否则不更新
        //CAS 是CPU的
        atomicInteger.compareAndSet(2020, 2021);
        System.out.println(atomicInteger.get());

        //   atomicInteger.compareAndSet(2020, 2021);
        //        System.out.println(atomicInteger.get());
        atomicInteger.compareAndSet(2020, 2021);
        System.out.println(atomicInteger.get());
//        Java无法操作内存
//        Java可以调用c++ native C ++可以操作内存
//        Java的后门．可以通过这个类操

        atomicInteger.getAndIncrement();


        //*Integer使用了对象缓存机制，默认范围是-128~127，
        // 推荐使用静态工厂方法valueof获取对象实例，而不是new ,因为valueOf使用缓存，
        // 而new一定会创建新的对象分配新的内存空间;
        AtomicStampedReference<Integer> reference = new AtomicStampedReference<>(1, 1);
        new Thread(() -> {
            int stamp = reference.getStamp();// 获得版本号
            System.out.println("a1=" + stamp);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("a===>" + reference.compareAndSet(1, 2,
                    reference.getStamp(), reference.getStamp() + 1));

            System.out.println("A2最新时间戳" + reference.getStamp());

            System.out.println("a===>" + reference.compareAndSet(2, 1,
                    reference.getStamp(), reference.getStamp() + 1));

            // 最新时间戳、版本号
            System.out.println("A3最新时间戳" + reference.getStamp());

        }, "a").start();

        new Thread(() -> {
            int stamp = reference.getStamp();// 获得版本号
            System.out.println("b1=" + stamp);
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("b===>" + reference.compareAndSet(1, 6,
                    reference.getStamp(),
                    reference.getStamp() + 1));

            System.out.println("b最新时间戳" + reference.getStamp());
        }, "b").start();

        Lock lock = new ReentrantLock();
    }
}
